﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.huawei.esdk.tp.professional.DataType;
using System.Numerics;
using System.Security.Cryptography;
using com.huawei.esdk.tp.professional.local;

namespace com.huawei.esdk.tp.professional.Utils
{
    internal class EncryptUtiles
    {
        private string EncryptMode = com.huawei.esdk.tp.professional.Utils.UtilsSettings.EncryptMode;
        RSA2048 rsa2048 = new RSA2048();

        public EncryptUtiles()
        {

        }

        // 加密方法
        public string EncryptMethod(string password)
        {
            string result = string.Empty;
            if (EncryptMode.Equals("RSA2048"))
            {
                result = RSA2048Encrypt(password, AuthorizeServiceEx.publicKey);
            }
            else if (EncryptMode.Equals("AES128_fixed"))
            {
                result = AES128_fixed(password);
            }
            else if (EncryptMode.Equals("Plaintext"))
            {
                result = password;
            }
            else
            {
                result = AES128_consulted(password, AuthorizeServiceEx.secretKey, AuthorizeServiceEx.iv);
            }
            return result;
        }

        /// <summary>
        /// RSA2048加密
        /// </summary>
        /// <param name="password">密码</param>
        /// <param name="publicKey">公钥</param>
        /// <returns>加密后的密码</returns>
        public string RSA2048Encrypt(string password, string publicKey)
        {
            byte[] keyByte = Convert.FromBase64String(publicKey);

            byte[] modulus = new byte[256];
            for (int i = 33; i < 289; i++)
            {
                modulus[i - 33] = keyByte[i];
            }

            byte[] exponent = new byte[3];
            for (int i = 291; i < keyByte.Length; i++)
            {
                exponent[i - 291] = keyByte[i];
            }

            //把3个变量转化为System.Numerics.BigInteger 
            var modulusBigInteger = new BigInteger(modulus);

            var exponentBigInteger = new BigInteger(exponent);

            var modulusBytes = modulusBigInteger.ToByteArray();

            var exponentBytes = exponentBigInteger.ToByteArray();

            var rsaCsp = new RSACryptoServiceProvider();
            RSAParameters parameters = new RSAParameters();
            parameters.Modulus = modulusBytes;
            parameters.Exponent = exponentBytes;
            rsaCsp.ImportParameters(parameters);

            var cipherbytes = rsaCsp.Encrypt(Encoding.UTF8.GetBytes(password), false);

            string cipher = Convert.ToBase64String(cipherbytes);
            return cipher;

        }

        /// <summary>
        /// AES128固定密钥加密
        /// </summary>
        /// <param name="password">密码</param>
        /// <returns>加密后密码</returns>
        public string AES128_fixed(string password)
        {
            RijndaelManaged rijndaelCipher = new RijndaelManaged();
            rijndaelCipher.Mode = CipherMode.CBC;
            rijndaelCipher.Padding = PaddingMode.PKCS7;
            rijndaelCipher.KeySize = 128;
            rijndaelCipher.BlockSize = 128;
            byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes("PASSWORD@ESDKNATIVE12");
            byte[] keyBytes = new byte[16];
            int len = pwdBytes.Length;
            if (len > keyBytes.Length)
                len = keyBytes.Length;
            System.Array.Copy(pwdBytes, keyBytes, len);
            rijndaelCipher.Key = keyBytes;
            byte[] ivBytes = System.Text.Encoding.UTF8.GetBytes("INITIAL@NATIVE12");
            rijndaelCipher.IV = ivBytes;
            ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
            byte[] plainText = Encoding.UTF8.GetBytes(password);
            byte[] cipherBytes = transform.TransformFinalBlock(plainText, 0, plainText.Length);
            return Convert.ToBase64String(cipherBytes);
        }

        /// <summary>
        /// 密钥协商的AES128加密     
        /// </summary>    
        public string AES128_consulted(string password, byte[] secretKey, byte[] iv)
        {
            RijndaelManaged rijndaelCipher = new RijndaelManaged();
            rijndaelCipher.Mode = CipherMode.CBC;
            rijndaelCipher.Padding = PaddingMode.PKCS7;
            rijndaelCipher.KeySize = 128;
            rijndaelCipher.BlockSize = 128;
            //byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes(secretKey);
            byte[] pwdBytes = secretKey;
            byte[] keyBytes = new byte[16];
            int len = pwdBytes.Length;
            if (len > keyBytes.Length)
                len = keyBytes.Length;
            System.Array.Copy(pwdBytes, keyBytes, len);
            rijndaelCipher.Key = keyBytes;
            byte[] ivBytes = iv;
            rijndaelCipher.IV = ivBytes;
            ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
            byte[] plainText = Encoding.UTF8.GetBytes(password);
            byte[] cipherBytes = transform.TransformFinalBlock(plainText, 0, plainText.Length);
            return Convert.ToBase64String(cipherBytes);
        }
    }
}
